package com.dz51.core.exception;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dz51.core.json.ViewResult;

/**
 * 异常过滤处理，针对业务异常封装成json响应
 */
public class ExceptionFilter implements Filter {

	private static Logger logger = LoggerFactory.getLogger(ExceptionFilter.class);

	@Override
	public void destroy() {
		if (logger.isDebugEnabled()) {
			logger.debug(" ExceptionFilter destroying......");
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
		try {
			HttpServletRequest rq = (HttpServletRequest) request;
			String agent = rq.getHeader("user-agent");
			Enumeration<String> enumera = rq.getParameterNames();
			StringBuffer params = new StringBuffer();
			String name = "";
			while (enumera.hasMoreElements()) {
				name = enumera.nextElement();
				params.append(name + ":" + rq.getParameter(name) + ";");
			}
			logger.debug("#clientMessage:" + agent + "\t" + rq.getHeader("referer") + "\t" + rq.getRequestURI() + "\t" + params);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		try {
			filterChain.doFilter(request, response);
		} catch (Exception exception) {
			logger.error("exception", exception);
			BusinessException businessException = null;
			if (exception instanceof BusinessException) {
				businessException = (BusinessException) exception;
			} else if (exception.getCause() instanceof BusinessException) {
				businessException = (BusinessException) exception.getCause();
			} else if (exception instanceof ServletException) {
				ServletException se = (ServletException) exception;
				if (se.getRootCause() instanceof BusinessException) {
					businessException = (BusinessException) se.getRootCause();
				}
			}
			if (businessException != null) {
				String resultJson = ViewResult.newInstance().state(businessException.getState(), businessException.getMessage()).json();
				out(response, resultJson);
				return;
			} else {
				if (logger.isDebugEnabled()) {
					logger.debug("异常未处理抛出。。。。");
				}
				if (exception instanceof ServletException) {
					throw (ServletException) exception;
				} else {
					throw new ServletException(exception);
				}
			}
		}
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		if (logger.isDebugEnabled())
			logger.debug(" ExceptionFilter initing.......");
	}

	/** 如果无权限，就调用此方法输出json数据 */
	private void out(ServletResponse response, String result) throws IOException {
		response.setContentType("application/json;charset=utf-8");
		response.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		out.println(result);
		out.flush();
		out.close();
	}

}
